home *** CD-ROM | disk | FTP | other *** search
/ Assassins - Ultimate CD Games Collection 4 / Assassins 4 (1999)(Weird Science).iso / misc / omega / source / gen2.c < prev    next >
C/C++ Source or Header  |  1997-05-02  |  11KB  |  469 lines

  1. /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
  2. /* gen2.c */
  3. /* level generator functions */
  4.  
  5. #include "glob.h"
  6.  
  7.  
  8.  
  9. /* For each level, there should be one stairway going up and one down. 
  10. fromlevel determines whether the player is placed on the up or the down
  11. staircase. The aux value is currently unused elsewhere, but is set 
  12. to the destination level. */
  13.  
  14. void make_stairs(fromlevel)
  15. int fromlevel;
  16. {
  17.   int i,j;
  18.   /* no stairway out of astral */
  19.   if (Current_Environment != E_ASTRAL) {
  20.     findspace(&i,&j,-1);
  21.     Level->site[i][j].locchar = STAIRS_UP;
  22.     Level->site[i][j].aux = Level->depth-1;
  23.     lset(i,j,STOPS);
  24.     if (fromlevel >= 0 && fromlevel < Level->depth) { 
  25.       Player.x = i;
  26.       Player.y = j;
  27.     }
  28.   }
  29.   if (Level->depth < MaxDungeonLevels) {
  30.     findspace(&i,&j,-1);
  31.     Level->site[i][j].locchar = STAIRS_DOWN;
  32.     Level->site[i][j].aux = Level->depth+1;
  33.     lset(i,j,STOPS);
  34.     if (fromlevel > Level->depth) { 
  35.       Player.x = i;
  36.       Player.y = j;
  37.     }
  38.   }
  39. }
  40.  
  41.  
  42.  
  43.  
  44.  
  45. /* tactical map generating functions */
  46.  
  47.  
  48. void make_country_screen(terrain)
  49. short terrain;
  50. {
  51.   int i,j;
  52.   TempLevel = Level;
  53.   if (ok_to_free(TempLevel)) {
  54. #ifndef SAVE_LEVELS
  55.     free_level(TempLevel);
  56. #endif
  57.     TempLevel = NULL;
  58.   }
  59. #ifndef SAVE_LEVELS
  60.   Level = ((plv) checkmalloc(sizeof(levtype)));
  61. #else
  62.   msdos_changelevel(TempLevel,0,-1);
  63.   Level = &TheLevel;
  64. #endif
  65.   clear_level(Level);
  66.   Level->environment = E_TACTICAL_MAP;
  67.   Level->generated = TRUE;
  68.   switch(terrain) {
  69.   case FOREST: make_forest(); break;
  70.   case JUNGLE: make_jungle(); break;
  71.   case SWAMP: make_swamp(); break;
  72.   case RIVER: make_river(); break;
  73.   case MOUNTAINS: case PASS: make_mountains(); break;
  74.   case ROAD: make_road(); break;
  75.   default: make_plains(); break;
  76.   }
  77.   if (nighttime()) {
  78.     print3("Night's gloom shrouds your sight.");    
  79.     for(i=0;i<WIDTH;i++)
  80.       for(j=0;j<LENGTH;j++) {
  81.     Level->site[i][j].showchar = SPACE;    
  82.     Level->site[i][j].lstatus = 0;
  83.       }
  84.   }
  85. }
  86.  
  87. void make_general_map(terrain)
  88. char *terrain;
  89. {
  90.   int i, j;
  91.   int size = strlen(terrain);
  92.   char curr;
  93.  
  94.   for (i=0;i<WIDTH;i++)
  95.     for (j=0;j<LENGTH;j++) {
  96.       if ((i == 0 && j == 0) || !random_range(5))
  97.     curr = terrain[random_range(size)];
  98.       else if (j == 0 || (random_range(2) && i > 0))
  99.     curr = Level->site[i - 1][j].locchar&0xff;
  100.       else
  101.     curr = Level->site[i][j - 1].locchar&0xff;
  102.       switch (curr) {
  103.     case (FLOOR&0xff):
  104.       Level->site[i][j].locchar = Level->site[i][j].showchar = FLOOR;
  105.       Level->site[i][j].p_locf = L_NO_OP;
  106.       break;
  107.     case (HEDGE&0xff):
  108.       Level->site[i][j].locchar = Level->site[i][j].showchar = HEDGE;
  109.       Level->site[i][j].p_locf = L_HEDGE;
  110.       break;
  111.     case (WATER&0xff):
  112.       Level->site[i][j].locchar = Level->site[i][j].showchar = WATER;
  113.       Level->site[i][j].p_locf = L_WATER;
  114.       break;
  115.     case (RUBBLE&0xff):
  116.       Level->site[i][j].locchar = Level->site[i][j].showchar = RUBBLE;
  117.       Level->site[i][j].p_locf = L_RUBBLE;
  118.       break;
  119.       }
  120.       Level->site[i][j].lstatus = SEEN+LIT;
  121.       Level->site[i][j].roomnumber = RS_COUNTRYSIDE;
  122.       if ((i == 0) || (j == 0) || (i == WIDTH-1) || (j == LENGTH-1))
  123.     Level->site[i][j].p_locf = L_TACTICAL_EXIT;
  124.     }
  125. }
  126.  
  127. void make_plains()
  128. {
  129.   make_general_map(".");
  130. }
  131.  
  132. void make_road()
  133. {
  134.   int x, y;
  135.   make_general_map("\"\"~4....");
  136.   for (x = WIDTH/2 - 3; x <= WIDTH/2 + 3; x++)
  137.     for (y = 0; y < LENGTH; y++) {
  138.       Level->site[x][y].locchar = Level->site[x][y].showchar = FLOOR;
  139.       if (y != 0 && y != LENGTH - 1)
  140.     Level->site[x][y].p_locf = L_NO_OP;
  141.     }
  142. }
  143.  
  144.  
  145.  
  146. void make_forest()
  147. {
  148.   make_general_map("\".");
  149.   straggle_corridor(0,random_range(LENGTH),WIDTH,random_range(LENGTH),
  150.     WATER,RS_COUNTRYSIDE);
  151. }
  152.  
  153.  
  154. void make_jungle()
  155. {
  156.   make_general_map("\"\".");
  157. }
  158.  
  159.  
  160. void make_river()
  161. {
  162.   int i,y,y1;
  163.   make_general_map("\".......");
  164.   y = random_range(LENGTH);
  165.   y1 = random_range(LENGTH);
  166.   straggle_corridor(0,y,WIDTH,y1,WATER,RS_COUNTRYSIDE);
  167.   for(i=0;i<7;i++) {
  168.     if (y > LENGTH/2) y--;
  169.     else y++;
  170.     if (y1 > LENGTH/2) y1--;
  171.     else y1++;
  172.     straggle_corridor(0,y,WIDTH,y1,WATER,RS_COUNTRYSIDE);
  173.   }
  174. }
  175.  
  176.  
  177. void make_mountains()
  178. {
  179.   int i,x,y,x1,y1;
  180.   make_general_map("4...");
  181.   x = 0;
  182.   y = random_range(LENGTH);
  183.   x1 = WIDTH;
  184.   y1 = random_range(LENGTH);
  185.   straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  186.   for(i=0;i<7;i++) {
  187.     x = random_range(WIDTH); 
  188.     x1 = random_range(WIDTH);
  189.     y = 0;
  190.     y1 = LENGTH;
  191.     straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  192.   }
  193. }
  194.  
  195.  
  196.  
  197. void make_swamp()
  198. {
  199.   make_general_map("~~\".");
  200. }
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. /* builds a room. Then, for each successive room, sends off at least one
  208. corridor which is guaranteed to connect up to another room, thus guaranteeing
  209. fully connected level. */
  210.  
  211. void room_level()
  212. {
  213.   int i,fx,fy,tx,ty,t,l,e;
  214.   char rsi;
  215.  
  216.   Level->numrooms = random_range(8)+9;
  217.  
  218.   do {
  219.     t = random_range(LENGTH-10)+1;
  220.     l = random_range(WIDTH-10)+1;
  221.     e = 4+random_range(5);
  222.   } while ((Level->site[l][t].roomnumber != RS_WALLSPACE) ||
  223.        (Level->site[l+e][t].roomnumber != RS_WALLSPACE) ||
  224.        (Level->site[l][t+e].roomnumber != RS_WALLSPACE) ||
  225.        (Level->site[l+e][t+e].roomnumber != RS_WALLSPACE));
  226.   if (Current_Dungeon == E_SEWERS) {
  227.     if (random_range(2)) rsi = ROOMBASE+25;
  228.     else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  229.   }
  230.   else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  231.   build_room(l,t,e,rsi,1);
  232.  
  233.  
  234.   for (i=2;i<=Level->numrooms;i++) {
  235.     do {
  236.       t = random_range(LENGTH-10)+1;
  237.       l = random_range(WIDTH-10)+1;
  238.       e = 4+random_range(5);
  239.     } while ((Level->site[l][t].roomnumber != RS_WALLSPACE) ||
  240.          (Level->site[l+e][t].roomnumber != RS_WALLSPACE) ||
  241.          (Level->site[l][t+e].roomnumber != RS_WALLSPACE) ||
  242.          (Level->site[l+e][t+e].roomnumber != RS_WALLSPACE));
  243.     if (Current_Dungeon == E_SEWERS) {
  244.       if (random_range(2)) rsi = ROOMBASE+25;
  245.       else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  246.     }
  247.     else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  248.     build_room(l,t,e,rsi,i);
  249.     
  250.  
  251.     /* corridor which is guaranteed to connect */
  252.     findspace(&tx,&ty,i);
  253.  
  254.     /* figure out where to start corridor from */
  255.     if ((ty <= t) && (tx <= l+e)) {
  256.       fx = l+1+random_range(e-1);
  257.       fy = t;
  258.     }
  259.     else if ((tx >= l+e) && (ty <= t+e)) {
  260.       fx = l+e;
  261.       fy = t+1+random_range(e-1);
  262.     }
  263.     else if ((ty >= t+e) && (tx >= l)) {
  264.       fx = l+1+random_range(e-1);
  265.       fy = t+e;
  266.     }
  267.     else {
  268.       fx = l;
  269.       fy = t+1+random_range(e-1);
  270.     }
  271.  
  272.     room_corridor(fx,fy,tx,ty,i);
  273.  
  274.  
  275.     /* corridor which may not go anywhere */
  276.     if (random_range(2)) {
  277.       findspace(&tx,&ty,i);
  278.       if ((ty <= t) && (tx <= l+e)) {
  279.     fx = l+1+random_range(e-1);
  280.     fy = t;
  281.       }
  282.       else if ((tx >= l+e) && (ty <= t+e)) {
  283.     fx = l+e;
  284.     fy = t+1+random_range(e-1);
  285.       }
  286.       else if ((ty >= t+e) && (tx >= l)) {
  287.     fx = l+1+random_range(e-1);
  288.     fy = t+e;
  289.       }
  290.       else {
  291.     fx = l;
  292.     fy = t+1+random_range(e-1);
  293.       }
  294.       room_corridor(fx,fy,tx,ty,i);
  295.     }
  296.   }
  297.  
  298.   if (Current_Dungeon == E_SEWERS) {
  299.     if (Level->depth == SEWERLEVELS) {
  300.       findspace(&tx,&ty,-1);
  301.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  302.       Level->mlist->next = NULL;
  303.       Level->mlist->m = 
  304.     Level->site[tx][ty].creature = 
  305.       ((pmt) make_creature(ML7+5)); /* The Great Wyrm */
  306.       Level->mlist->m->x = tx;
  307.       Level->mlist->m->y = ty;
  308.     }
  309.   }
  310.   else if (Current_Environment == E_CASTLE) {
  311.     if (Level->depth == CASTLELEVELS) {
  312.       findspace(&tx,&ty,-1);
  313.       Level->site[tx][ty].locchar = STAIRS_DOWN;
  314.       Level->site[tx][ty].p_locf = L_ENTER_COURT;
  315.     }
  316.   }
  317.   else if (Current_Environment == E_VOLCANO) {
  318.     if (Level->depth == VOLCANOLEVELS && !gamestatusp(COMPLETED_VOLCANO)) {
  319.       findspace(&tx,&ty,-1);
  320.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  321.       Level->mlist->next = NULL;
  322.       Level->mlist->m = 
  323.     Level->site[tx][ty].creature = 
  324.       ((pmt) make_creature(ML10+4)); /* The demon emp */
  325.       Level->mlist->m->x = tx;
  326.       Level->mlist->m->y = ty;
  327.     }
  328.   }
  329. }
  330.  
  331.  
  332.  
  333. /* goes from f to t unless it hits a site which is not a wall and doesn't
  334.    have buildaux field == baux */
  335. void room_corridor(fx,fy,tx,ty,baux)
  336. int fx,fy,tx,ty,baux;
  337. {
  338.   int dx,dy,continuing = TRUE;
  339.  
  340.   dx = sign(tx-fx);
  341.   dy = sign(ty-fy);
  342.  
  343.   makedoor(fx,fy);
  344.  
  345.   fx+=dx;
  346.   fy+=dy;
  347.  
  348.   while(continuing) {
  349.     Level->site[fx][fy].locchar = FLOOR;
  350.     Level->site[fx][fy].roomnumber = RS_CORRIDOR;
  351.     Level->site[fx][fy].buildaux = baux;
  352.     dx = sign(tx-fx);
  353.     dy = sign(ty-fy);
  354.     if ((dx != 0) && (dy != 0)) {
  355.       if (random_range(2)) dx = 0;
  356.       else if (random_range(2)) dy = 0;
  357.     }
  358.     fx+=dx;
  359.     fy+=dy;
  360.     continuing = (((fx != tx) || (fy != ty)) &&
  361.           ((Level->site[fx][fy].buildaux == 0) ||
  362.            (Level->site[fx][fy].buildaux == baux)));
  363.   }
  364.   makedoor(fx,fy);
  365. }
  366.  
  367.  
  368.  
  369.  
  370.  
  371. void maze_level()
  372. {
  373.   int i,j,tx,ty,mid;
  374.   char rsi;
  375.   if (Current_Environment == E_ASTRAL)
  376.     switch(Level->depth){
  377.     case 1: rsi = RS_EARTHPLANE; break;
  378.     case 2: rsi = RS_AIRPLANE; break;
  379.     case 3: rsi = RS_WATERPLANE; break;
  380.     case 4: rsi = RS_FIREPLANE; break;
  381.     case 5: rsi = RS_HIGHASTRAL; break;
  382.     }
  383.   else rsi = RS_VOLCANO;
  384.   maze_corridor(random_range(WIDTH-1)+1,
  385.         random_range(LENGTH-1)+1,
  386.         random_range(WIDTH-1)+1,
  387.         random_range(LENGTH-1)+1,
  388.         rsi,0);
  389.   if (Current_Dungeon == E_ASTRAL) {
  390.     for(i=0;i<WIDTH;i++) 
  391.       for(j=0;j<LENGTH;j++) 
  392.     if (Level->site[i][j].locchar == WALL)
  393.       switch(Level->depth){
  394.       case 1: Level->site[i][j].aux = 500; break;
  395.       case 2: 
  396.         Level->site[i][j].locchar = WHIRLWIND;
  397.         Level->site[i][j].p_locf = L_WHIRLWIND;
  398.         break;
  399.       case 3: 
  400.         Level->site[i][j].locchar = WATER;
  401.         Level->site[i][j].p_locf = L_WATER;
  402.         break;
  403.       case 4:
  404.         Level->site[i][j].locchar = FIRE;
  405.         Level->site[i][j].p_locf = L_FIRE;
  406.         break;
  407.       case 5: 
  408.         Level->site[i][j].locchar = ABYSS;
  409.         Level->site[i][j].p_locf = L_ABYSS;
  410.         break;
  411.       }
  412.     switch(Level->depth) {
  413.     case 1: mid = ML10+5; break; /* Elemental Lord of Earth */
  414.     case 2: mid = ML10+6; break; /* Elemental Lord of Air */
  415.     case 3: mid = ML10+7; break; /* Elemental Lord of Water */
  416.     case 4: mid = ML10+8; break; /* Elemental Lord of Fire */
  417.     case 5: mid = ML10+9; break; /* Elemental Master */
  418.     }
  419.     if (Level->depth == 5) {
  420.       findspace(&tx,&ty,-1);
  421.       Level->site[tx][ty].p_locf = L_ENTER_CIRCLE;
  422.       Level->site[tx][ty].locchar = STAIRS_DOWN;
  423.     }
  424.     if (! gamestatusp(COMPLETED_ASTRAL)) {
  425.       findspace(&tx,&ty,-1);
  426.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  427.       Level->mlist->next = NULL;
  428.       Level->mlist->m = 
  429.     Level->site[tx][ty].creature = 
  430.       ((pmt) make_creature(mid)); 
  431.       Level->mlist->m->x = tx;
  432.       Level->mlist->m->y = ty;
  433.     }
  434.   }
  435.   else if (Current_Environment == E_VOLCANO) {
  436.     if (Level->depth == VOLCANOLEVELS && !gamestatusp(COMPLETED_VOLCANO)) {
  437.       findspace(&tx,&ty,-1);
  438.       Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
  439.       Level->mlist->next = NULL;
  440.       Level->mlist->m = 
  441.     Level->site[tx][ty].creature = 
  442.       ((pmt) make_creature(ML10+4)); /* The demon emp */
  443.       Level->mlist->m->x = tx;
  444.       Level->mlist->m->y = ty;
  445.     }
  446.   }
  447. }
  448.  
  449.  
  450. /* keep drawing corridors recursively for 2^5 endpoints */
  451. void maze_corridor(fx,fy,tx,ty,rsi,num)
  452. int fx,fy,tx,ty;
  453. char rsi,num;
  454. {
  455.   if (num < 6) {
  456.     straggle_corridor(fx,fy,tx,ty,FLOOR,rsi);
  457.     maze_corridor(tx,ty,
  458.           random_range(WIDTH-1)+1,
  459.           random_range(LENGTH-1)+1,
  460.           rsi,num+1);
  461.     
  462.   }
  463. }
  464.  
  465.  
  466.  
  467.  
  468.  
  469.